using System;
using System.Collections.Generic;

using Lizk.SimpleHUD;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;
using Lizk.DShowPlayer;
using SharpMedia.Controls;
using System.Data;
using System.Linq;
using MediaData;

namespace SharpMedia.Pages
{
    public class MainMenuPage : MediaPage
    {

        HUDContainerSimple subLists = new HUDContainerSimple() { Anchor = Anchor.All };
        private HUDLabel titleLabel, typeLabel, clock;
        private HUDImage typeSelection, selection;
        SizeS itemSize = new SizeS(160, 160);
        private HUDCenterList list;
        HUDContainerSimple listContainer, typeContainer;
        TripTrigger selectionTrigger = new TripTrigger(new TimeSpan(0, 0, 0, 0, 200));
        
        
        public void InitializeComponents()
        {
            listContainer = new HUDContainerSimple() {
                Bounds = new RectangleS(0, 0, Bounds.Width, 500),
                Anchor = Anchor.All ^ Anchor.Bottom
            };
            Add(new HUDCentering(this, listContainer));

            typeContainer = new HUDContainerSimple();
            typeContainer.Bounds = Bounds;
            typeContainer.Alpha = 0;
            typeContainer.MovementStopped += new EventHandler(delegate { typeLabel.Fade(255, 6f); });
            Add(typeContainer);

            typeLabel = new HUDLabel("", "tahoma23b");
            typeLabel.Bounds = new RectangleS(70, 0, 250, 64);
            typeLabel.Alignment = Lizk.SimpleHUD.Alignment.VCenter | Lizk.SimpleHUD.Alignment.Left;
            typeLabel.Alpha = 0;
            typeContainer.Add(typeLabel);

            typeSelection = new HUDImage();
            typeSelection.Alpha = 127;
            typeSelection.OnMouseEnter += new EventHandler<MouseEventArgs>(delegate(object o, MouseEventArgs args) { ((HUDImage)o).Fade(255, 6f); });
            typeSelection.OnMouseExit += new EventHandler<MouseEventArgs>(delegate(object o, MouseEventArgs args) { ((HUDImage)o).Fade(127, 6f); });
            typeSelection.OnMouseDown += new EventHandler<MouseEventArgs>(delegate(object o, MouseEventArgs args) { SharpMedia.Back(); });
            typeContainer.Add(typeSelection);

            list = new HUDCenterList(itemSize);
            list.Bounds = new RectangleS(0, 0, Bounds.Width, itemSize.Height);
            list.Anchor = Anchor.All ^ Anchor.Bottom;
            listContainer.Add(list);


            list.CenterOffset = new PointS(-itemSize.Width * 1.5f, 0);

            selectionTrigger.TimeOut += new EventHandler(selectionTrigger_TimeOut);


            titleLabel = new HUDLabel("Muh", "tahoma38b");
            titleLabel.Bounds = new RectangleS(0, list.Bounds.Bottom + 10, Bounds.Width, 40);
            //titleLabel.Anchor = Anchor.All;
            //titleLabel.Alignment = Lizk.SimpleHUD.Alignment.Left | Lizk.SimpleHUD.Alignment.Top;
            titleLabel.Text = "";
            titleLabel.Alpha = 0;
            Add(titleLabel);

            selection = new HUDImage("white.png");
            selection.ConstrainProportions = false;
            selection.Alpha = 127;
            selection.Color = ColorS.Black;
            Add(selection);

            clock = new HUDLabel("00:00", "tahoma50b");
            clock.Color = ColorS.White;
            clock.Anchor = Anchor.Left | Anchor.Right | Anchor.Bottom;
            clock.Alignment = Lizk.SimpleHUD.Alignment.Right | Lizk.SimpleHUD.Alignment.VCenter;
            clock.Bounds = new RectangleS(10, Bounds.Height - 83, Bounds.Width - 20, 80);
            Add(clock);

            GenerateMainMenuItems();

            list.SelectedIndexChanged += new EventHandler<SelectionEventArgs>(list_SelectedIndexChanged);
            list.SetSelectedIndex(0, false);
            list.SetStartIndex((int)(Bounds.Width / itemSize.Width / -2f), false);

            subLists.Bounds = new RectangleS(0, titleLabel.AbsoluteBounds.Bottom, Size.Width, Size.Height - titleLabel.AbsoluteBounds.Bottom);

            Add(subLists);


        }

        void GenerateMainMenuItems()
        {
            List<MainMenuItem> items = new List<MainMenuItem>();
            var titles = (from f in SharpMedia.Database.Data.Titles
                          group f by f.Type into g
                          select new { Type = g.Key, Group = g.Count() });


            var dict = titles.ToDictionary(x => x.Type);
            
            for (int i = 0; i < typeItems.Length; i++)
            {
                if (dict.ContainsKey(typeItems[i].Type))
                    items.Add(typeItems[i]);
            }

            items.Add(new MainMenuItem(MainMenuItem.MenuAction.FileBrowser, "files.png", "File Browser", "glow.png"));
            items.Add(new MainMenuItem(MainMenuItem.MenuAction.DVDs, "dvd.png", "DVD", "glow.png"));


            foreach (var item in items)
            {
                var control = new MainMenuItemControl(item, itemSize);
                list.Add(control);

                // make a sublist for the control
                control.SubList = new MainMenuSubList();
                subLists.Add(control.SubList);
                
                PopulateList(control.Item, control.SubList.List);
                
                control.SubList.List.MoveItems(false);
                
                control.SubList.SelectionImage.Bounds = control.SubList.List.Selection;
            }



        }

        MainMenuItem[] typeItems = new MainMenuItem[] { new MainMenuItem(MainMenuItem.MenuAction.ListType, "tvshows.png", "TV-Shows", "glow.png") { Type = "tvshows" }, new MainMenuItem(MainMenuItem.MenuAction.ListType, "movies.png", "Movies", "glow.png") { Type = "movies" }, new MainMenuItem(MainMenuItem.MenuAction.ListType, "anime.png", "Anime", "glow.png") { Type = "anime" } };

        void UpdateLists()
        {
            List<MainMenuItem> items = new List<MainMenuItem>();
            var titles = (from f in SharpMedia.Database.Data.Titles
                          group f by f.Type into g
                          select new { Type = g.Key, Group = g.Count() });


            var dict = titles.ToDictionary(x => x.Type);
            int index = 0;
            
            for (int i = 0; i < typeItems.Length; i++)
            {
                if (dict.ContainsKey(typeItems[i].Type))
                {
                    if (list.Get<MainMenuItemControl>(index).Item.Type != typeItems[i].Type)
                    {
                        MainMenuItem item = typeItems[i];
                        var control = new MainMenuItemControl(item, itemSize);
                        list.Insert(index, control);

                        // make a sublist for the control
                        control.SubList = new MainMenuSubList();
                        subLists.Insert(index, control.SubList);

                        PopulateList(control.Item, control.SubList.List);

                        control.SubList.List.MoveItems(false);

                        control.SubList.SelectionImage.Bounds = control.SubList.List.Selection;
                        if (list.SelectedIndex == index)
                            list.SelectedIndex++;
                    }
                    else
                    {
                        PopulateList(list.Get<MainMenuItemControl>(index).Item, list.Get<MainMenuItemControl>(index).SubList.List);

                        list.Get<MainMenuItemControl>(index).SubList.List.MoveItems(true);
                        list.Get<MainMenuItemControl>(index).SubList.SelectionImage.Destination = list.Get<MainMenuItemControl>(index).SubList.List.Selection.Location;

                    }
                    index++;
                }
                else
                {
                    if (list.Get<MainMenuItemControl>(index).Item.Type == typeItems[i].Type)
                    {

                        subLists.Remove(list.Get<MainMenuItemControl>(index).SubList);
                        if (list.SelectedIndex > index)
                            list.SelectedIndex--;
                        list.RemoveAt(index);

                    }

                }
            }
            
            for (int i = dict.Count; i < list.Count; i++)
            {
                PopulateList(list.Get<MainMenuItemControl>(i).Item, list.Get<MainMenuItemControl>(i).SubList.List);
                list.Get<MainMenuItemControl>(i).SubList.List.MoveItems(true);
                list.Get<MainMenuItemControl>(i).SubList.SelectionImage.Destination = list.Get<MainMenuItemControl>(i).SubList.List.Selection.Location;
            }
            list.MoveItems(true);
            list_SelectedIndexChanged(this, new SelectionEventArgs(-1, true));
        }

        void list_SelectedIndexChanged(object sender, SelectionEventArgs e)
        {
            selectionTrigger.Trigger();
            titleLabel.Fade(0, 10f);
            if (e.OldIndex >= 0 && e.OldIndex < list.Count)
            {
                MainMenuItemControl menuItem = list.Get<MainMenuItemControl>(e.OldIndex);
                list.Get<HUDContainerSimple>(e.OldIndex)[1].Fade(127, 6f);
                list.Get<HUDContainerSimple>(e.OldIndex)[0].Fade(0, 6f);
                menuItem.SubList.Fade(0, 10f);
            }

            if (e.Animate)
            {
                list.GetSelectedControl<HUDContainerSimple>()[0].Fade(255, 6f);
                list.GetSelectedControl<HUDContainerSimple>()[1].Fade(255, 6f);
            }
            else
            {
                list.GetSelectedControl<HUDContainerSimple>()[0].Alpha = 255;
                list.GetSelectedControl<HUDContainerSimple>()[1].Alpha = 255;

            }
        }

        void selectionTrigger_TimeOut(object sender, EventArgs e)
        {
              MainMenuItemControl selectedItem = list.GetSelectedControl<MainMenuItemControl>();
            titleLabel.Text = selectedItem.Item.Name;

            titleLabel.Location = selectedItem.Location + list.AbsoluteBounds.Location + new PointS(0, list.Selection.Size.Height - 10);
            titleLabel.Destination = list.Selection.Location + list.AbsoluteBounds.Location + new PointS(0, list.Selection.Size.Height - 10);

            if (SharpMedia.CurrentPage == this)
                titleLabel.Fade(255, 7f);

            

            
            subLists.Bounds = new RectangleS(0, titleLabel.AbsoluteBounds.Bottom, Size.Width, Size.Height - titleLabel.AbsoluteBounds.Bottom);

            selectedItem.SubList.Fade(255, 7f);
            selectedItem.SubList.Location = new PointS(selectedItem.AbsoluteBounds.X, 0);
            selectedItem.SubList.Destination = new PointS(list.Selection.Location.X, 0);
            selectedItem.SubList.Size = new SizeS(subLists.Bounds.Width - selectedItem.SubList.Destination.X, subLists.Size.Height);
        }



        public override void ResizeMove(RectangleS oldRect, RectangleS newRect)
        {
            base.ResizeMove(oldRect, newRect);
            if (titleLabel != null)
                selectionTrigger_TimeOut(this, null);
        }
       
        
        protected override void MediaChanged(MediaDataSet obj)
        {
            SharpMedia.Engine.Wait();
            UpdateLists();
            SharpMedia.Engine.Resume();
            selectionTrigger_TimeOut(this, null);
        }

        void PopulateList(MainMenuItem menuItam, HUDMoveList list)
        {
            switch (menuItam.Action)
            {
                case MainMenuItem.MenuAction.ListType:
                    ListTVShows(list, menuItam.Type, "All " + menuItam.Name);
                    break;
                case MainMenuItem.MenuAction.FileBrowser:
                    list.Clear();
                    foreach (QuickLink ql in SharpMedia.Settings.QuickLinks)
                    {
                        HUDControl item = new MainMenuSubListItem(this.list, list.ItemSize, ql.Image, ql.Title, ql.Subtitle);
                        item.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);

                        item.Tag = ql.Directory;
                        list.Add(item);
                    }


                    foreach (DriveInfo di in DriveInfo.GetDrives())
                    {
                        if (di.DriveType == DriveType.Network && !Lizk.Utilities.Net.NetworkDrive.IsNetworkDriveOnline(di.RootDirectory.FullName, 1000))
                            continue;

                        if (di.IsReady)
                        {
                            string driveIcon = "harddisk.png";
                            switch (di.DriveType)
                            {
                                case DriveType.CDRom:
                                    driveIcon = "CDROM.png";
                                    break;
                                case DriveType.Fixed:
                                case DriveType.Network:
                                    driveIcon = "harddisk.png";
                                    break;
                            }

                            HUDControl item = new MainMenuSubListItem(this.list, list.ItemSize, driveIcon, di.Name, di.VolumeLabel);
                            item.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);

                            item.Tag = di.RootDirectory.FullName;
                            list.Add(item);
                        }
                    }
                    break;
                case MainMenuItem.MenuAction.DVDs:
                    list.Clear();
                    string[] dvds = Util.AvailableDVDs();
                    if (dvds.Length == 0)
                    {
                        list.Add(new MainMenuSubListItem(this.list, list.ItemSize, "no.png", "No DVDs Inserted", ""));
                    }
                    else
                    {
                        for (int j = 0; j < dvds.Length; j++)
                        {
                            DriveInfo di = new DriveInfo(dvds[j]);
                            HUDControl c = new MainMenuSubListItem(this.list, list.ItemSize, "CDROM.png", di.Name + " " + di.VolumeLabel, "");
                            c.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);
                            c.Tag = dvds[j];

                            list.Add(c);
                        }
                    }
                    break;

            }
        }
        void item_OnMouseUp(object sender, HUDControl.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                HUDContainerSimple c = (HUDContainerSimple)sender;
                HUDMoveList sublist = (HUDMoveList)c.Parent;

                int listindex = ((HUDContainerSimple)sublist.Parent.Parent).IndexOf(sublist.Parent);
                if (listindex != list.SelectedIndex)
                    return;

                int index = sublist.IndexOf(c);
                if (index > -1)
                {
                    if (sublist.SelectedIndex == index)
                    {
                        Command(HUDCommands.Select, null);
                    }
                    else
                        sublist.SelectedIndex = index;

                }
            }
        }
        private void ListMovies(HUDMoveList list, string type, string allText)
        {
            // Save previously selected movie
            int newSelectedIndex = 0;
            MediaDataSet.TitlesRow selectedFile = list.SelectedControl == null ? null : (MediaDataSet.TitlesRow)list.SelectedControl.Tag;

            // Reset List
            list.Clear();
            HUDControl allItem = new MainMenuSubListItem(this.list, list.ItemSize, "folder.png", allText, "");
            allItem.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);
            list.Add(allItem);
            // Grab newest movies

            var titles = from t in SharpMedia.Database.Data.Titles
                         where t.Type == type && !Util.IsTitleOffline(t)
                         orderby t.GetFilesRows().Max(f => f.DateAdded) descending, t.GetFilesRows().Max(f => f.LastModified) descending
                         select t;


            foreach (MediaDataSet.TitlesRow title in titles)
            {
                string artwork = SharpMedia.ImageCache.TryGetImagePath(title, "film.png");
                int days = ((int)DateTime.Now.Subtract(DateTime.FromFileTime(title.GetFilesRows().Max(f => f.DateAdded))).TotalDays);

                string date = "";
                if (days > -1)
                {
                    if (days == 0)
                        date = "Today";
                    else if (days == 1)
                        date = "Yesterday";
                    else
                        date = days + " days ago";
                }


                HUDControl item = new MainMenuSubListItem(this.list, list.ItemSize, artwork, title.Name, date);
                item.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);
                item.Tag = title;
                list.Add(item);

                // Select the previously select movie
                if (selectedFile != null && selectedFile == title)
                    newSelectedIndex = list.Count - 1;

            }

            // Do select
            list.SelectedIndex = newSelectedIndex;
            list.MoveItems(false);


        }

        private void ListTVShows(HUDMoveList list, string type, string allText)
        {
            MediaDataSet.TitlesRow selectedFile = list.SelectedControl == null ? null : (MediaDataSet.TitlesRow)list.SelectedControl.Tag;
            int newSelectedIndex = 0;
            list.Clear();
            HUDControl allItem = new MainMenuSubListItem(this.list, list.ItemSize, "folder.png", allText, "");
            allItem.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);
            list.Add(allItem);
            //DataRow currentEp = GetSelectedType() == "tvshow" ? GetSelectedRow() : null;

            var titles = from t in SharpMedia.Database.Data.Titles
                         where t.Type == type &&
                            (from e in t.GetEpisodesRows()
                             where e.Watched != 1 &&
                                 (from ef in e.GetEpisodeFilesRows() where SharpMedia.RootManager.IsOnline(ef.FilesRowParent.Volume) select ef).Count() > 0
                             select e).Count() > 0
                         orderby t.GetFilesRows().Max(f => f.DateAdded) descending, t.GetFilesRows().Max(f => f.LastModified) descending
                         select t;

            var titles2 = from t in SharpMedia.Database.Data.Titles
                          where t.Type == type &&
                            (from f in t.GetFilesRows()
                             where SharpMedia.RootManager.IsOnline(f.Volume) && (f.GetEpisodeFilesRows().Count() == 0 || f.GetEpisodeFilesRows().Any(e => e.EpisodesRow.Watched == 0))
                             select f).Count() > 0
                          orderby t.GetFilesRows().Max(f => f.DateAdded) descending, t.GetFilesRows().Max(f => f.LastModified) descending
                          select t;


            foreach (var title in titles2)
            {

                int days = ((int)DateTime.Now.Subtract(DateTime.FromFileTime(title.GetFilesRows().Max(f => f.DateAdded))).TotalDays);
                string date = "";
                if (days > -1)
                {
                    if (days == 0)
                        date = "Today";
                    else if (days == 1)
                        date = "Yesterday";
                    else
                        date = days + " days ago";
                }


                HUDControl item = new MainMenuSubListItem(this.list, list.ItemSize,
                    SharpMedia.ImageCache.TryGetImagePath(title, "film.png"),
                    title.Name,
                date
                );
                item.OnMouseUp += new EventHandler<MouseEventArgs>(item_OnMouseUp);
                item.Tag = title;
                list.Add(item);

                if (selectedFile != null && selectedFile.Id == title.Id)
                    newSelectedIndex = list.Count - 1;


            }


            list.SelectedIndex = newSelectedIndex;
            list.MoveItems(false);
        }


        private void TypeSelected(RectangleS selectionBounds, string image, string text)
        {
            typeSelection.File = image;
            typeContainer.Bounds = list.Selection + list.AbsoluteBounds.Location;
            typeSelection.Size = typeContainer.Size;
            typeContainer.MovementSpeed = 10f;
            typeContainer.Destination = new PointS(10, 10);
            typeContainer.DestinationSize = new PointS(392, 64);
            typeSelection.DestinationSize = new PointS(64, 64);
            typeContainer.Fade(255, 6f);
            typeLabel.Text = list.GetSelectedControl<MainMenuItemControl>().Item.Name;
        }
        private void HideTypeSelection()
        {
            typeLabel.Alpha = 0;
            typeContainer.Alpha = 0;
        }
        public MainMenuPage(MediaPage parent)
            : base(parent)
        {
            InitializeComponents();
        }


        public override void Update(TimeSpan ts)
        {
            base.Update(ts);
            selectionTrigger.Update(ts);
            clock.Text = DateTime.Now.ToString("HH:mm");

        }

        public override void Command(HUDCommands command, object tag)
        {
            HUDMoveList subList;
            object tt = null;
            switch (command)
            {
                case HUDCommands.Up:
                case HUDCommands.Down:
                    subList = list.GetSelectedControl<MainMenuItemControl>().SubList.List;
                    if (command == HUDCommands.Up)
                        subList.SelectedIndex--;
                    else
                        subList.SelectedIndex++;
                    break;
                case HUDCommands.Left:
                    if (list.Count == 0)
                        break;
                    list.SelectedIndex--;
                    
                    break;
                case HUDCommands.Right:
                    if (list.Count == 0)
                        break;
                    list.SelectedIndex++;
                    
                    break;
                case HUDCommands.Preset3:
                    SharpMedia.Navigate(new HarddiskConfigPage(this));
                    break;
                case HUDCommands.Select:
                    SharpMedia.Engine.Wait();
                    
                    GridTitleSelectionPage tsp;
                    MainMenuItemControl selectedItem = list.GetSelectedControl<MainMenuItemControl>();

                    switch (selectedItem.Item.Action)
                    {
                        case MainMenuItem.MenuAction.ListType:
                            if (!SharpMedia.CanUseDatabase)
                                break;

                            tt = selectedItem.SubList.List.SelectedControl.Tag;
                            TypeSelected(list.Selection, selectedItem.Item.Image, selectedItem.Item.Name);
                            if (tt == null)
                            {
                                tsp = new GridTitleSelectionPage(this, selectedItem.Item.Type);
                                SharpMedia.Navigate(tsp);
                            }
                            else
                            {
                                MediaDataSet.TitlesRow title = (MediaDataSet.TitlesRow)tt;

                                if (title.GetEpisodesRows().Count() > 0)
                                {
                                    MediaDataSet.EpisodesRow ep = Util.SelectEarliestUnwatchedEpisode(title);

                                    HUDImage img = selectedItem.SubList.List.GetSelectedControl<HUDContainerSimple>().Get<HUDImage>(1);

                                    EpisodeSelectionPage eps = new EpisodeSelectionPage(this, title, img.AbsoluteBounds, selectedItem.SubList.List.GetSelectedControl<HUDContainer>().Get<HUDImage>(1).ImageSize.Size, ep);
                                    SharpMedia.Navigate(eps);
                                }
                                else
                                {
                                    MovieInfoPage mip = new MovieInfoPage(this, (MediaDataSet.TitlesRow)tt);
                                    SharpMedia.Navigate(mip);

                                }



                            }
                            break;
                        case MainMenuItem.MenuAction.FileBrowser:
                            tt = selectedItem.SubList.List.SelectedControl.Tag;
                            TypeSelected(list.Selection, selectedItem.Item.Image, selectedItem.Item.Name);
                            if (tt == null)
                            {
                                FileBrowserPage fbp = new FileBrowserPage(this);
                                SharpMedia.Navigate(fbp);
                            }
                            else
                            {
                                FileBrowserPage fbp = new FileBrowserPage(this, (string)tt);
                                SharpMedia.Navigate(fbp);

                            }
                            break;
                        case MainMenuItem.MenuAction.TvDevice:
                            LiveTVPage tvPage = new LiveTVPage(this, RectangleS.Empty, (TvSettings)list.SelectedControl.Tag);
                            SharpMedia.Navigate(tvPage);
                            break;
                        case MainMenuItem.MenuAction.DVDs:
                            tt = selectedItem.SubList.List.SelectedControl.Tag;
                            if (tt == null)
                                break;

                            string s = (string)tt;
                            DriveInfo di = new DriveInfo(s);
                            VideoList vl = new VideoList();
                            vl.Add(new VideoSource(di.VolumeLabel, s));

                            PlayerPage dvp = new PlayerPage(this, vl);
                            SharpMedia.Navigate(dvp);
                            break;
                    }
                    SharpMedia.Engine.Resume();

                    break;
                default:
                    if (parent != null)
                        parent.Command(command, tag); ;
                    break;
            }
        }

       
        public override void Deactivate()
        {
            listContainer.Fade(0, 6f);
            titleLabel.Fade(0, 6f);
            subLists.Fade(0, 6f);
            clock.Fade(0, 6f);
            base.Deactivate();
        }

        public override void Activate()
        {
            listContainer.Fade(255, 6f);
            titleLabel.Fade(255, 6f);
            subLists.Fade(255, 6f);
            clock.Fade(255,6f);
            HideTypeSelection();
            SharpMedia.Engine.Wait();
            lock (SharpMedia.UpdateLockObject)
            {
                if(!SharpMedia.UpdateLock)
                    UpdateLists();
            }
            selectionTrigger_TimeOut(this, null);
            SharpMedia.Engine.Resume();

            base.Activate();
        }



        
    }

    

}